home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
ddjgrep.zip
/
TOOLS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1987-11-04
|
9KB
|
504 lines
/*---------------------------------------------------------------------------
* TOOLS.C the expression parser used by grep
*
*
* Copyright (c) 1984 Allen Holub
* Copyright (c) 1984 Software Engineering Consultants
* P.O. Box 5679
* Berkeley, CA. 94705
*
* All rights reserved.
*
* This program may be copied for personal, non-commmercial use
* only, provided that this copyright notice is included in all
* copies and that this program is not modified in any way.
* Copying for any other use without previously obtaining the
* written permission of the author is prohibited.
*
*---------------------------------------------------------------------------
*/
#include <stdio.h>
#include "tools.h"
#include <ctype.h>
#include <malloc.h>
#include <string.h>
/* This module contains the various routines needed by grep
* to match regular expressions. Routines are ordered alphabeticaly.
*/
int amatch(lin, pat,boln)
char *lin, *boln;
TOKEN *pat;
{
register char *bocl, *rval, *strstart;
if (pat == 0) return (0);
strstart = lin;
while (pat)
{
if (pat->tok == CLOSURE && pat->next)
{
pat = pat->next;
bocl = lin;
while (*lin && omatch(&lin, pat))
;
if (pat = pat->next)
{
while (bocl <= lin)
{
if (rval = amatch(lin, pat, boln))
return(rval);
else
--lin;
}
return (0);
}
}
else if ( omatch(&lin, pat, boln) )
pat = pat->next;
else
return(0);
}
return ( max(strstart , --lin) );
}
/* ----------------------------------------------------------------------- */
delete (ch, str)
int ch;
register char *str;
{
ch &= 0xff;
while (*str && *str != ch)
str++;
while (*str)
{
*str = *(str+1);
str++;
}
}
/* ----------------------------------------------------------------------- */
int dodash(delim, src, map)
int delim;
char *src, *map;
{
register int first,last;
char *start;
start = src;
while (*src && *src != delim)
{
if (*src != '-')
setbit (esc(&src),map,1);
else if (src == start || *(src+1) == delim)
setbit ('-',map,1);
else
{
src++;
if (*src < *(src-2))
{
first = *src;
last = *(src-2);
}
else
{
first = *(src-2);
last = *src;
}
while (++first <= last)
setbit(first,map,1);
}
src++;
}
return (src);
}
/* ------------------------------------------------------------------------ */
int esc(s)
char **s;
{
register int rval;
if (**s != ESCAPE)
rval = **s;
else
{
(*s)++;
switch (toupper(**s))
{
case '\000': rval = ESCAPE; break;
case 'S': rval = ' ' ; break;
case 'N': rval = '\n' ; break;
case 'T': rval = '\t' ; break;
case 'B': rval = '\b' ; break;
case 'R': rval = '\r' ; break;
default: rval = **s ;
}
}
return (rval);
}
/* ----------------------------------------------------------------------- */
TOKEN *getpat(arg)
char *arg;
{
return (makepat(arg, '\000'));
}
/* ----------------------------------------------------------------------- */
insert(ch, str)
int ch;
register char *str;
{
register char *bp;
bp = str;
while (*str)
str++;
do
{
*(str+1) = *str;
str--;
} while (str >= bp);
*bp = ch;
}
/* ----------------------------------------------------------------------- */
char *in_string(delim,str)
register int delim;
register char *str;
{
delim &= 0x7f;
while (*str && *str != delim)
str++;
return (*str ? str : 0);
}
/* ----------------------------------------------------------------------- */
int isalphanum(c)
int c;
{
return (('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z') ||
('0' <= c && c <= '9')
);
}
/* ----------------------------------------------------------------------- */
TOKEN *makepat(arg, delim)
char *arg;
int delim;
{
TOKEN *head, *tail;
TOKEN *ntok;
char buf[CLS_SIZE];
int error;
if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE)
return (0);
error = 0;
head = 0;
tail = 0;
while (*arg && *arg != delim && *arg != '\n' && !error)
{
ntok = malloc(TOKSIZE);
ntok->bitmap = &(ntok->lchar);
ntok->lchar = '\000';
ntok->next = 0;
switch (*arg)
{
case ANY:
ntok->tok = ANY;
break;
case BOL:
if (head==0)
ntok->tok = BOL;
else
error = 1;
break;
case EOL:
if (*(arg+1) == delim || *(arg+1) == '\000'
|| *(arg+1) == '\n')
ntok->tok = EOL;
else
error = 1;
break;
case CCL:
if (*(arg+1) == NEGATE)
{
ntok->tok = NCCL;
arg += 2;
}
else
{
ntok->tok = CCL;
arg++;
}
if (ntok->bitmap = makebitmap(128))
arg = dodash(CCLEND,arg,ntok->bitmap);
else
{
fprintf (stderr,"Not enough memory for pat\n");
error = 1;
}
break;
case CLOSURE:
if (head != 0)
{
switch (tail->tok)
{
case BOL:
case EOL:
case CLOSURE:
return(0);
default:
ntok->tok = CLOSURE;
}
}
break;
default:
ntok->tok = LITCHAR;
ntok->lchar = esc(&arg);
}
if (error || ntok == 0)
{
unmakepat(head);
return (0);
}
else if (head == 0)
{
ntok->next = 0;
head = tail = ntok;
}
else if (ntok->tok != CLOSURE)
{
tail->next = ntok;
ntok->next = tail;
tail = ntok;
}
else if (head != tail)
{
(tail->next)->next = ntok;
ntok->next = tail;
}
else
{
ntok->next = head;
tail->next = ntok;
head = ntok;
}
arg++;
}
tail->next = 0;
return (head);
}
/* ----------------------------------------------------------------------- */
char *matchs(line,pat,ret_endp)
char *line;
TOKEN *pat;
int ret_endp;
{
char *rval, *bptr;
bptr = line;
while (*line)
{
if ((rval = amatch(line, pat,bptr)) == 0)
line++;
else
{
rval = ret_endp ? rval : line ;
break;
}
}
return (rval);
}
/* ----------------------------------------------------------------------- */
stoupper(str)
char *str;
{
char *rval;
rval = str;
while (*str)
{
if ('a' <= *str && *str <= 'z')
*str -= ('a' - 'A');
str++;
}
return (rval);
}
/* ----------------------------------------------------------------------- */
int max(x,y)
int x,y;
{
return ((x>y) ? x : y);
}
/* ----------------------------------------------------------------------- */
int omatch (linp, pat, boln)
char **linp, *boln;
TOKEN *pat;
{
register int advance;
advance = -1;
if ( **linp )
{
switch (pat->tok)
{
case LITCHAR:
if (**linp == pat->lchar)
advance = 1;
break;
case BOL:
if (*linp == boln)
advance = 0;
break;
case ANY:
if (**linp != '\n')
advance = 1;
break;
case EOL:
if (**linp == '\n')
advance = 0;
case CCL:
if (testbit (**linp, pat->bitmap))
advance = 1;
break;
case NCCL:
if (!testbit(**linp, pat->bitmap))
advance = 1;
break;
default:
printf("omatch: can't happen\n");
}
}
if (advance >= 0)
*linp += advance;
return (++advance);
}
/* ----------------------------------------------------------------------- */
pr_line(ln)
register char *ln;
{
for (;*ln;ln++)
{
if ((' ' <= *ln) && (*ln <= '~'))
putchar (*ln);
else
{
printf ("\\0x%02x", *ln);
if (*ln == '\n')
putchar ('\n');
}
}
}
/* ----------------------------------------------------------------------- */
pr_tok(head)
TOKEN *head;
{
int i;
register char *str;
for (;head;head=head->next)
{
if (head->tok == BOL)
str = "BOL";
else
switch (head->tok)
{
case EOL:
str = "EOL";
break;
case ANY:
str = "ANY";
break;
case LITCHAR:
str = "LITCHAR";
break;
case ESCAPE:
str = "ESCAPE";
break;
case CCL:
str = "CCL";
break;
case CCLEND:
str = "CCLEND";
break;
case NEGATE:
str = "NEGATE";
break;
case NCCL:
str = "NCCL";
break;
case CLOSURE:
str = "CLOSURE";
break;
default:
str = "**** unknown ****";
}
printf("%-8s at: 0x%x, ", str, head);
if (head->tok == CCL || head->tok == NCCL)
{ printf ("string (at 0x%x) =<",head->bitmap);
for (i = 0;i < 0x7f;i++)
if (testbit(i,head->bitmap))
putchar(i);
printf (">, ");
}
else if (head->tok == LITCHAR)
printf ("lchar = %c, ", head->lchar);
printf